/*
* Copyright (c) 2016 . All Rights Reserved.
*/
package com.cgmnx.admin.web.controller.rbac;

import com.cgmnx.admin.biz.rbac.RoleBiz;
import com.cgmnx.admin.biz.rbac.UserBiz;
import com.cgmnx.admin.common.bean.ApiRes;
import com.cgmnx.admin.common.bean.CurrentUserInfo;
import com.cgmnx.admin.common.bean.Limiter;
import com.cgmnx.admin.common.bean.UserContext;
import com.cgmnx.admin.common.constants.WebConstant;
import com.cgmnx.admin.common.exception.Preconditions;
import com.cgmnx.admin.common.util.WebUtils;
import com.cgmnx.admin.dao.entity.rbac.RoleEntity;
import com.cgmnx.admin.dao.entity.rbac.UserEntity;
import com.cgmnx.admin.service.rbac.UserService;
import com.cgmnx.admin.web.converter.entity.UserEntityConverter;
import com.cgmnx.admin.web.converter.vm.UserVmConverter;
import com.cgmnx.admin.web.model.param.UpdatedPasswordParam;
import com.cgmnx.admin.web.model.param.UserParam;
import com.cgmnx.admin.web.model.vm.UserVm;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Optional;
import com.google.common.base.Splitter;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: created  Date: 16/12/12 Time: 下午3:02
 * @version: 1.0
 */
@Slf4j
@Controller
public class UserController {

    private static final Joiner JOINER = Joiner.on(",").skipNulls();

    @Autowired
    private UserBiz userBiz;
    @Autowired
    private UserService userService;

    @Autowired
    private RoleBiz roleBiz;

    @Autowired
    private UserEntityConverter userEntityConverter;

    @Autowired
    private UserVmConverter userVmConverter;

    @Value("${no_delete_roleId}")
    private String noDeleteRoleId;


    @RequestMapping("/cgmnx/rbac/user/save.json")
    @ResponseBody
    public ApiRes save(@Validated @RequestBody UserParam userParam, BindingResult result) {

        if (result.hasErrors()) {
            return ApiRes.returnFail(WebUtils.resolveBindingResult(result));
        }

        Preconditions.checkArgument(StringUtils.equals(userParam.getPassword(), userParam.getRepassword()), "两次密码不一致");

        UserEntity entity = userEntityConverter.convert(userParam);

        Optional<UserEntity> userEntityOptional = userBiz.queryByUserId(entity.getUserId());

        if (userEntityOptional.isPresent()) {
            return ApiRes.returnFail("该用户已经存在");
        }

        Integer id = userBiz.save(entity);

        if (id < 1) {
            return ApiRes.returnFail("保存失败");
        }

        return ApiRes.returnSuccess("保存成功");
    }

    @RequestMapping(value = "/cgmnx/rbac/user/updatePassword.json", method = RequestMethod.POST)
    @ResponseBody
    public ApiRes updatePassword(@CookieValue("_u") String userId,
                                 @Validated @RequestBody UpdatedPasswordParam passwordParam, BindingResult bindingResult) {

        if (bindingResult.hasErrors()) {
            return ApiRes.returnFail(WebUtils.resolveBindingResult(bindingResult));
        }

        Preconditions.checkNotNull(StringUtils.equals(passwordParam.getNewPassword(), passwordParam.getNewRePassword()), "两次密码不一致");

        Optional<UserEntity> userEntityOptional = userBiz.queryByUserId(userId);
        if (!userEntityOptional.isPresent()) {
            return ApiRes.returnFail("该用户不存在");
        }


        boolean result = userBiz.updatePassword(userEntityOptional.get(), passwordParam.getOldPassword(), passwordParam.getNewPassword());

        return ApiRes.returnSuccess(result);
    }

    @RequestMapping("/cgmnx/rbac/user/update.json")
    @ResponseBody
    public ApiRes update(@Validated @RequestBody UserParam userParam, BindingResult result) {

        if (result.hasErrors()) {
            return ApiRes.returnFail(WebUtils.resolveBindingResult(result));
        }

        Optional<UserEntity> userEntityOptional1 = userService.queryUserByEmail(userParam.getUserEmail());
        if (userEntityOptional1.isPresent()) {
            return ApiRes.returnFail("该邮箱已经存在");
        }

        Optional<UserEntity> userEntityOptional = userBiz.queryById(userParam.getId());

        if (!userEntityOptional.isPresent()) {
            return ApiRes.returnFail("该用户不存在");
        }

        UserEntity entity = userEntityConverter.convert(userParam);
        userBiz.update(entity);
        return ApiRes.returnSuccess();
    }

    @RequestMapping("/cgmnx/rbac/user/enable.json")
    @ResponseBody
    public ApiRes enable(@RequestParam(value = "idList") List<Integer> idList) {

        if (CollectionUtils.isEmpty(idList)) {
            return ApiRes.returnFail("请选择用户");
        }

        userBiz.enable(idList, UserContext.getUserInfo());
        return ApiRes.returnSuccess();
    }

    @RequestMapping("/cgmnx/rbac/user/disable.json")
    @ResponseBody
    public ApiRes disable(@RequestParam("idList") final List<Integer> idList) {

        if (CollectionUtils.isEmpty(idList)) {
            return ApiRes.returnFail("请选择用户");
        }

        CurrentUserInfo userInfo = UserContext.getUserInfo();

        List<UserEntity> userEntities = userBiz.queryByIdList(idList);

        Preconditions.checkArgument(CollectionUtils.isNotEmpty(userEntities), "请选择用户");

        List<String> userNameList = FluentIterable.from(userEntities).transform(new Function<UserEntity, String>() {

            @Override
            public String apply(UserEntity input) {
                return input.getUserId();
            }
        }).toList();

        if (userNameList.contains(userInfo.getUserId())) {
            return ApiRes.returnFail("管理员不能删除自己");
        }

        List<RoleEntity> roleEntityList = roleBiz.queryByUserIdList(userNameList);
        List<Integer> roleIdList = roleEntityList.stream().map(input -> input.getId()).collect(Collectors.toList());

        Iterable<String> split = Splitter.on(",").omitEmptyStrings().split(noDeleteRoleId);

        if (CollectionUtils.containsAny(FluentIterable.from(split).transform(new Function<String, Integer>() {

            @Override
            public Integer apply(String input) {
                return Integer.valueOf(input);
            }
        }).toList(), roleIdList)) {
            return ApiRes.returnFail("不能删除这些角色(" + noDeleteRoleId + ")的用户");
        }

        userBiz.disable(idList, userInfo);
        return ApiRes.returnSuccess();
    }

    @RequestMapping("/cgmnx/rbac/user/query.json")
    @ResponseBody
    public ApiRes query(@RequestParam("id") Integer id) {

        if (id == null) {
            return ApiRes.returnFail("请选择用户");
        }

        Optional<UserEntity> userEntityOptional = userBiz.queryById(id);

        if (!userEntityOptional.isPresent()) {
            return ApiRes.returnFail("用户不存在");
        }

        UserEntity userEntity = userEntityOptional.get();
        UserVm convert = userVmConverter.convert(userEntity);

        List<RoleEntity> roleEntityList = roleBiz.queryByUserIdList(Lists.<String>newArrayList(userEntity.getUserId()));
        if (CollectionUtils.isNotEmpty(roleEntityList)) {
            convert.setRoleName(JOINER.join(FluentIterable.from(roleEntityList).transform(new Function<RoleEntity, String>() {

                @Override
                public String apply(RoleEntity input) {
                    return input.getUserId();
                }
            })));
            ImmutableList<Integer> integers = FluentIterable.from(roleEntityList).transform(new Function<RoleEntity, Integer>() {

                @Override
                public Integer apply(RoleEntity input) {
                    return input.getId();
                }
            }).toList();
            convert.setRoleId(integers);
        }

        return ApiRes.returnSuccess(convert);
    }


    @RequestMapping("/cgmnx/rbac/user/queryPage.json")
    @ResponseBody
    public ApiRes queryPage(@RequestParam(value = "userId", required = false) String userId,
                            @RequestParam(value = "userName", required = false) String userName,
                            @RequestParam(value = "offset", required = false, defaultValue = WebConstant.DEFAULT_PAGE_OFFSET) Integer offset,
                            @RequestParam(value = "pageSize", required = false, defaultValue = WebConstant.DEFAULT_PAGE_SIZE) Integer pageSize
    ) {


        int count = userBiz.count(userName, userId);

        if (count <= 0) {
            return ApiRes.emptyList();
        }

        Limiter limiter = Limiter.create(offset, pageSize);

        List<UserEntity> userEntities = userBiz.queryPage(userName, userId, limiter);

        if (CollectionUtils.isEmpty(userEntities)) {
            return ApiRes.emptyList();
        }


        List<UserVm> userVmImmutableList = userVmConverter.convert(userEntities);

        return ApiRes.list(userVmImmutableList, count);

    }


}